package com.yuanzong.wuliu.controller.intercdeptor;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yuanzong.wuliu.common.enums.status.StatusEnum;
import com.yuanzong.wuliu.common.vo.ApiResult;
import com.yuanzong.wuliu.model.system.user.SystemUser;
import com.yuanzong.wuliu.service.system.user.factory.SystemUserFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class AdminHandlerInterceptorAdapter implements HandlerInterceptor {

    // 不拦截的Url集合
    private static List<String> notInterceptUrls = new ArrayList<>();

    static {
        ///////////////////////////////////     不拦截URL  ///////////////////////////////////
        // 认证接口
        notInterceptUrls.add("/admin/auth/auth/**");
        notInterceptUrls.add("/admin/base/code/photo");
    }

    // 登录用户Map<token, 用户ID>
    private static Map<String, Long> loginUserMap = new HashMap<>();

    // 当前线程操作用户
    private static ThreadLocal<SystemUser> threadLocal = new ThreadLocal<>();
    private static ThreadLocal<String> threadLocalToken = new ThreadLocal<>();

    public static SystemUser getRuntimeUser() {
        return threadLocal.get();
    }

    public static String getRuntimeToken() {
        return threadLocalToken.get();
    }

    public static void setRuntimeUser(String token, Long userId) {
        loginUserMap.put(token, userId);
    }

    public static void removeRuntimeUser(String token) {
        loginUserMap.remove(token);
    }

    /**
     * 目标方法执行之前
     * 登录检查写在这里，如果没有登录，就不执行目标方法
     *
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String resultMsg = "无效的Token";
        // 获取进过拦截器的路径
        String requestURI = request.getRequestURI();
        requestURI = requestURI.substring(request.getContextPath().length());
        // 不拦截URL过滤验证
        for (String notInterceptUrl : notInterceptUrls) {
            if (notInterceptUrl.endsWith("/**")) {
                notInterceptUrl = notInterceptUrl.substring(0, notInterceptUrl.length() - 3);
                if (requestURI.startsWith(notInterceptUrl)) {
                    return true;
                }
            }
            if (notInterceptUrl.endsWith("**")) {
                notInterceptUrl = notInterceptUrl.substring(0, notInterceptUrl.length() - 2);
                if (requestURI.startsWith(notInterceptUrl)) {
                    return true;
                }
            }
            if (requestURI.equals(notInterceptUrl)) {
                return true;
            }
        }
        // 登陆验证
        String token = request.getHeader("authorization");
        if (token != null) {
            try {
                Long userId = loginUserMap.get(token);
                if (userId != null) {
                    SystemUser systemUser = SystemUserFactory.getSystemUserService().getById(userId);
                    if (systemUser != null) {
                        if (systemUser.getStatus().equals(StatusEnum.IS_USE.getValue())) {
                            threadLocal.set(systemUser);
                            threadLocalToken.set(token);
                            return true;
                        }
                        resultMsg = "用户已被冻结";
                    }
                    loginUserMap.remove(token);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 验证不通过代表无权限
        response.setContentType("text/json;charset=utf-8");
        response.getWriter().print(new ObjectMapper().writeValueAsString(ApiResult.instance(ApiResult.TOKEN_ILLEGAL, resultMsg)));
        return false;
    }

    /**
     * 目标方法执行完成以后
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        // 销毁当前线程用户
        if (threadLocal.get() != null) {
            threadLocal.remove();
            threadLocalToken.remove();
        }
        HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
    }

    /**
     * 页面渲染以后
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
    }

}
